﻿//AcademicPlanner - course registration planning web app.
//Copyright (C) 2009  Boubacar Diallo

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AcademicPlanner.Data.Entities;
using NHibernate.Tool.hbm2ddl;
using NHibernate;

namespace AcademicPlanner.Data.Repositories
{
	/// <summary>
	/// RegistrationEntityRepository serves as the repository for <c>RegistrationEntity</c>s.
	/// </summary>
	/// <since>1.0</since>
	public class RegistrationEntityRepository : EntityRepository<RegistrationEntity>
    {
		internal override string DBTableName { get { return "registrations"; } }

		/// <summary>
		/// Gets the prefix for named queries of <c>RegistrationEntity</c>s.
		/// </summary>
		/// <since>1.0</since>
		protected override string NamedQueriesPrefix
		{
			get
			{
				return "RegistrationEntity";
			}
		}


		class InstanceHolder
		{
			internal static RegistrationEntityRepository INSTANCE = new RegistrationEntityRepository();
		}


		/// <summary>
		/// Gets the single RegistrationEntityRepository instance.
		/// </summary>
		/// <returns>The single instance of RegistrationEntityRepository.</returns>
		/// <since>1.0</since>
		internal static RegistrationEntityRepository GetInstance()
		{
			return InstanceHolder.INSTANCE;
		}

		private IList<RegistrationEntity> 
			QueryByPeriodEntityYearAndPeriodEntityTermEntitySeqOrder(IQuery pQuery, 
																		int pYear, 
																		int pTermEnitySeqOrder)
		{
			IList<RegistrationEntity> rEnts = new List<RegistrationEntity>();

			try
			{
				pQuery.SetInt32("year", pYear);
				pQuery.SetInt32("periodEntityTermEntitySeqOrder", pTermEnitySeqOrder);
				rEnts = pQuery.List<RegistrationEntity>();
			}
			catch (HibernateException vHx)
			{
				var vDx = new DataException(DataErrorCode.QUERY_REGISTRATION_ENTITY_BY_PERIODENTITY_YEAR_AND_PERIODENTITY_TERMENTITY_SEQORDER_FAILED, vHx);
				throw vDx;
			}

			return rEnts;
		}

		/// <summary>
		/// Filters a collection of <c>RegistrationEntity</c>s to keep only the ones that
		/// have a <c>PeriodEntity</c> anterior to the provided year and term position in
		/// a year.
		/// </summary>
		/// <remarks>
		/// A <see cref="T:AcademicPlanner.Data.DataException"/> may be inderectly
		/// thrown with error code <c>DataErrorCode.QUERY_REGISTRATION_ENTITY_BY_PERIODENTITY_YEAR_AND_PERIODENTITY_TERMENTITY_SEQORDER_FAILED</c>
		/// when an error is reported by NHibernate. The <c>HibernateException</c> is
		/// accessible via the <c>InnerException</c> property.
		/// </remarks>
		/// <param name="pFilterList">The collection to filter.</param>
		/// <param name="pYear">The year.</param>
		/// <param name="pTermEnitySeqOrder">The position of the academic term in a year.</param>
		/// <returns>A filtered collection.</returns>
		/// <since>1.0</since>
		public IList<RegistrationEntity> FilterByAnteriorPeriodEntity(ICollection pFilterList, int pYear, 
																		int pTermEnitySeqOrder)
		{
			IList<RegistrationEntity> rEnts;
			var vFilterQuery = "where (PeriodEntity.Year = :year and PeriodEntity.TermEntity.Seq_Order < :periodEntityTermEntitySeqOrder) or (PeriodEntity.Year < :year)";
			var vFilter = GetFilterQuery(pFilterList, vFilterQuery);

			DSAS.DisableFilters();
			rEnts = QueryByPeriodEntityYearAndPeriodEntityTermEntitySeqOrder(vFilter, pYear, pTermEnitySeqOrder);
			DSAS.EnableFilters();

			return rEnts;
		}
	}
}
